package com.niodata.dp.mybatis;

import com.niodata.dp.collection.WrappedList;
import com.niodata.dp.util.JsonUtil;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

public abstract class AbstractWrappedListTypeHandler<T> extends BaseTypeHandler<WrappedList<T>>
      implements DpMybatisTypeHandler {

  public abstract Class getEntityType();

  @Override
  public JdbcType getJdbcType() {
    return JdbcType.LONGVARCHAR;
  }

  @Override
  public Class getTypeHandlerClass() {
    return this.getClass();
  }

  public abstract Class<? extends WrappedList> getJavaClass();

  @Override
  public void setNonNullParameter(
        PreparedStatement ps, int i, WrappedList parameter, JdbcType jdbcType) throws SQLException {
    try {
      String json = JsonUtil.toJson(parameter);
      ps.setString(i, json);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public WrappedList getNullableResult(ResultSet rs, String columnName) throws SQLException {
    String json = rs.getString(columnName);
    if (json == null || json.length() == 0) {
      return null;
    }
    try {
      Class entityClass = getEntityType();
      WrappedList wrappedList = getJavaClass().newInstance();
      List list = JsonUtil.fromJsonList(entityClass, json);
      wrappedList.setList(list);
      return wrappedList;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  @Override
  public WrappedList getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    String json = rs.getString(columnIndex);
    if (json == null || json.length() == 0) {
      return null;
    }
    try {
      Class entityClass = getEntityType();
      WrappedList wrappedList = getJavaClass().newInstance();
      List list = JsonUtil.fromJsonList(entityClass, json);
      wrappedList.setList(list);
      return wrappedList;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  @Override
  public WrappedList getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return null;
  }
}
